import json
import os
import time
from datetime import datetime, timedelta
from pathlib import Path
from typing import Any, Dict, Optional
import hashlib

from src.logger import logger


class CacheManager:
    """管理金融数据缓存系统"""
    
    def __init__(self, cache_dir: str = "cache/financial_data"):
        self.cache_dir = Path(cache_dir)
        self.cache_dir.mkdir(parents=True, exist_ok=True)
        
        # 不同数据类型的缓存时间配置（单位：秒）
        self.cache_durations = {
            "realtime": 300,        # 5分钟 - 实时数据
            "daily": 3600 * 4,     # 4小时 - 日级数据
            "kline": 3600 * 2,     # 2小时 - K线数据
            "capital_flow": 1800,  # 30分钟 - 资金流向
            "announcement": 3600 * 24,  # 24小时 - 公告数据
            "financial": 3600 * 12,    # 12小时 - 财务数据
            "sentiment": 1800,     # 30分钟 - 市场情绪
            "hot_money": 900,      # 15分钟 - 游资数据
        }
    
    def _get_cache_key(self, data_type: str, identifier: str, **kwargs) -> str:
        """生成缓存键"""
        key_parts = [data_type, identifier]
        if kwargs:
            sorted_kwargs = sorted(kwargs.items())
            key_parts.extend([f"{k}={v}" for k, v in sorted_kwargs])
        
        key_string = "_".join(key_parts)
        return hashlib.md5(key_string.encode()).hexdigest()
    
    def _get_cache_path(self, cache_key: str) -> Path:
        """获取缓存文件路径"""
        return self.cache_dir / f"{cache_key}.json"
    
    def get(self, data_type: str, identifier: str, **kwargs) -> Optional[Dict[str, Any]]:
        """从缓存获取数据"""
        try:
            cache_key = self._get_cache_key(data_type, identifier, **kwargs)
            cache_path = self._get_cache_path(cache_key)
            
            if not cache_path.exists():
                return None
            
            # 检查缓存是否过期
            cache_duration = self.cache_durations.get(data_type, 3600)
            cache_age = time.time() - cache_path.stat().st_mtime
            
            if cache_age > cache_duration:
                logger.debug(f"缓存过期: {cache_key} (age: {cache_age:.0f}s > {cache_duration}s)")
                return None
            
            # 读取缓存数据
            with open(cache_path, 'r', encoding='utf-8') as f:
                cached_data = json.load(f)
            
            logger.debug(f"缓存命中: {cache_key}")
            return cached_data
            
        except Exception as e:
            logger.warning(f"读取缓存失败: {str(e)}")
            return None
    
    def set(self, data_type: str, identifier: str, data: Dict[str, Any], **kwargs) -> bool:
        """保存数据到缓存"""
        try:
            cache_key = self._get_cache_key(data_type, identifier, **kwargs)
            cache_path = self._get_cache_path(cache_key)
            
            # 确保缓存目录存在
            cache_path.parent.mkdir(parents=True, exist_ok=True)
            
            # 保存数据
            with open(cache_path, 'w', encoding='utf-8') as f:
                json.dump(data, f, ensure_ascii=False, indent=2)
            
            logger.debug(f"缓存保存: {cache_key}")
            return True
            
        except Exception as e:
            logger.error(f"保存缓存失败: {str(e)}")
            return False
    
    def clear_old_cache(self, max_age_days: int = 7) -> int:
        """清理过期缓存"""
        cleared_count = 0
        cutoff_time = time.time() - (max_age_days * 24 * 3600)
        
        for cache_file in self.cache_dir.glob("*.json"):
            if cache_file.stat().st_mtime < cutoff_time:
                try:
                    cache_file.unlink()
                    cleared_count += 1
                except Exception as e:
                    logger.warning(f"删除缓存文件失败 {cache_file}: {str(e)}")
        
        logger.info(f"清理了 {cleared_count} 个过期缓存文件")
        return cleared_count


# 全局缓存管理器实例
cache_manager = CacheManager()